/**
 * Component 与 PureComponent 的区别
 */

import React from 'react'

const isObject = function isObject(obj) {
  return obj !== null && /(function|object)$/.test(typeof obj)
}

const shallowEqual = function shallowEqual(A, B) {
  // 1. null 和 非对象类型的数据直接排除，不进行比较
  if (!isObject(A) || !isObject(B)) return false

  // 2. 两个对象指向的是同一个对象 -> 同一个对象表示他们是相等的
  if (A === B) return true

  // 3. 比较两个对象的 key 值数是否一样，如果不一样则证明对象发生了改变
  let keysA = Reflect.ownKeys(A), keysB = Reflect.ownKeys(B);

  if (keysA.length !== keysB.length) return false;

  // 4. 属性比较
  for (let i = 0; i < keysA.length; i++) {
    let key = keysA[i]
    // A 中的属性 key 在 B 中不存在；A[key] !== B[key]; 使用 Object.is() 方法是为了解决 NaN === NaN : false 的问题，默认认为 NaN === NaN 为 true
    if (!Object.prototype.hasOwnProperty.call(B, key) || !Object.is(A[key], B[key])) return false;
  }

  // 排除以上后，则证明这两个对象是相等的(这里的相等说的是对象内部成员相等，而不是堆内存相等)
  return true;
}

class DemoTwo extends React.Component {
  // class DemoTwo extends React.PureComponent {
  state = {
    arr: [10, 20, 30]
  }

  box3 = React.createRef()

  constructor(props) {
    super(props)
  }

  render() {
    let { arr } = this.state

    return <div>
      {
        arr.map((item, index) => {
          return (<span key={index} style={{
            display: 'inline-block',
            width: 100,
            height: 100,
            background: 'pink',
            marginRight: 20,
          }}>
            {item}
          </span>)
        })
      }

      <br />
      <button onClick={() => {
        arr.push(40)
        console.log('arr::: ', this.state.arr)
        this.setState({
          arr
        })
      }}>新增span</button>

      <br />
      {/* <p ref='demoP'>显示一段文本</p> */}
      {/* <p ref={x => this.box2 = x}>显示一段文本</p> */}
      <p ref={this.box3}>显示一段文本</p>
    </div>
  }

  // shouldComponentUpdate(nextProps, nextState) {
  //   let { props, state } = this
  //   return !shallowEqual(props, nextProps) || !shallowEqual(state, nextState)
  // }

  componentDidMount() {
    // console.log('refs ::: ', this.refs['demoP'])
    // console.log('refs ::: ', this.box2)
    console.log('refs ::: ', this.box3.current)
  }
}

export default DemoTwo